<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/26 0026
 * Time: 下午 5:54
 */

namespace app\api\controller;


use app\admin\model\Store;
use app\admin\model\Tenantdistributiontype;
use app\common\BaseHelper;
use app\common\model\Groupdetail;
use app\common\model\Useraccountdetails;
use app\lib\dadaapi\ToolsInco;
use app\common\DictConstant;
use app\common\model\Dadareasons;
use app\common\model\Distributionrecord;
use app\common\model\Orderproductdetail;
use app\common\model\Proofrefund;
use app\common\model\Querydeliverfee;
use app\common\model\Refundorder;
use app\common\model\Salerule;
use app\common\model\User;
use app\common\validate\CancelRefund;
use app\common\validate\getLogistics;
use app\common\validate\IDMustBePostiveInt;
use app\common\validate\OrderPlace;
use app\api\service\Token as TokenService;
use app\api\service\Order as OrderService;

use app\common\validate\Refund;
use app\common\validate\WriteOffOrder;
use app\lib\exception\ParameterException;
use distribution\DadaAddOrder;
use kuaidiniao\KuaiDiniaoApi;
use think\Db;
use think\Exception;
use think\Request;


class Order extends BaseController
{
    // 用户在选择商品后，向ＡＰＩ提交包含它所选择商品的相关信息
    // API在接收到信息后，需要检查订单相关商品的库存量
    // 有库存，把订单数据存入数据库中= 下单成功了，返回客户端消息，告诉客户端可以支付了
    // 调用我们的支付接口，进行支付
    // 还需要再次进行库存量检测
    // 服务器这边就可以调用微信的支付接口进行支付
    // 小程序根据服务器返回的结果拉起微信支付
    // 微信会返回给我们一个支付的结果（异步）
    // 成功：也需要进行库存量的检查
    // 成功：进行库存量的扣除

    // 做一次库存量检测
    // 创建订单
    // 减库存--预扣除库存
    // if pay 真正的减库存
    // 在一定时间内30min没有去支付这个订单，我们需要还原库存

    // 在PHP里写一个定时器，每隔1min去遍历数据库，找到那些超时的
    // 订单，把这些订单给还原库存
    // linux crontab

    // 任务队列
    // 订单任务加入到任务队列里
    // redis

    //定时器，每隔1s，5s，访问API的接口

    protected $beforeActionList = [
        'checkExclusiveScope' => ['only' => 'placeOrder,ConfirmCollectGoods,refund,queryDeliverFee']
    ];

//orderQuery

    public function placeOrder()
    {
        (new OrderPlace())->goCheck();
        $products = input('post.products/a');
        $uid = TokenService::getCurrentUid();
        $orderdata= input('post.');
        $orderdata['tenantid'] = TokenService::getTenantid();
        $commissions = $this->Commissions($uid,TokenService::getTenantid());
        if($commissions['saleRuleId']){
            $orderdata['saleRuleId'] = $commissions['saleRuleId'];
        }
        unset($orderdata['products']);
        $order = new OrderService();
        $status = $order->place($uid, $orderdata, $products);
        if(!$status['pass']){
            return show(config('status.ERROR_STATUS'), '创建订单失败，库存不足', $status);
        }else{
            return show(config('status.SUCCESS_STATUS'), '创建订单成功', $status);
        }

    }

    //判断该订单是否产生佣金（主要是看该下单用户是否有上级）
    private function Commissions($uid,$Tenantid){
        $isCommissions = [
            'saleRuleId' => NULL
        ];
        $user = User::get($uid);
        if($user->chiefUserId){
            $chief = User::get($user->chiefUserId);
            if($chief->tenantId == $Tenantid){
                $sale = Salerule::where('tenantId','=',$Tenantid)->find();
                if($sale){
                    $isCommissions['saleRuleId'] = $sale->id;
                }

            }
        }

        return $isCommissions;

    }

    //用户订单确认收货
    public function ConfirmCollectGoods(){
        //修改订单状态
        //判断该订单是否有佣金，如果有则为对应的上级用户添加佣金
        //判断该笔订单是否需要赠送积分
        (new IDMustBePostiveInt())->goCheck();
        $orderID = input('post.id');
        $order = new OrderService();
        return $order->ConfirmCollectGoods($orderID);

    }

    //订单售后
    public function refund(){
        //1.订单确认收货后不能再申请售后
        //2.商户拒绝售后之后不能再重新申请
        //2.到店订单核销之后不能再申请售后
        (new Refund())->goCheck();
        $order = new OrderService();
        return $order->refund(input('post.'));
    }

    //取消订单售后
    public function CancelRefund(){
        //1.判断售后订单状态 status = 4
        (new CancelRefund())->goCheck();
        $postData = input('post.');
        Db::startTrans();
        try{
            $ordermodel = new \app\common\model\Order();
            $refund = Refundorder::where(['orderNO'=>$postData['orderNO'],'productId'=>$postData['productId']])->find();
            $this->checkRefund($refund);
            $refund->status = Refundorder::STATUS_5;
            $refund->save();
            $refunds = Refundorder::where(['orderNO'=>$postData['orderNO'],'status'=>Refundorder::STATUS_4])->count();
            if($refunds == 0){
                //如果该订单
                $order = $ordermodel->where('orderNO',$postData['orderNO'])->find();
                $Orderproductdetail = Orderproductdetail::get($refund->orderProductDetailId);
                $order->status = $Orderproductdetail->oldStatus;
                $order->save();
            }
            Db::commit();
            return show(config('status.SUCCESS_STATUS'),'取消售后申请成功','取消售后申请成功');
        }catch (Exception $ex){
            Db::rollback();
            return show(config('status.ERROR_STATUS'),$ex->msg,'取消售后失败');
        }


    }

    private function checkRefund($refund){
        if(!$refund || $refund->status != 4){
            throw new ParameterException([
                'msg' => '该订单不能售后'
            ]);
        }

    }


    //取消未付款订单
    public function cancelOrder(){
        //参数，订单id,
        (new IDMustBePostiveInt())->goCheck();
        $orderId = input('post.id');
        $order = new OrderService();

        return $order->cancelOrder($orderId);
    }




    /**
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 订单列表
     */
    public function getOrder()
    {
        $uid = \app\api\service\Token::getCurrentUid();
        $param = self::getHttpParam();
        $start = $param->start;
        $length = $param->length;
        if(empty($param->status)) {
            $count = count(\app\common\model\Order::where(['createUser'=>$uid])->order('create_time desc')->select());
            $order = \app\common\model\Order::where(['createUser'=>$uid])->order('create_time desc')->limit($start,$length)->select();

            if (empty($order)) {
                return show(config('status.EMPTY_STATUS'), self::NOT_DATA, '未查到订单信息');
            } else {
                for ($i = 0; $i < count($order); $i++) {
                    $orderProductDetail = Orderproductdetail::where('orderId', $order[$i]->id)->order('create_time desc')->select();
                    $order[$i]['products'] = $orderProductDetail;
                }
                return show_page(config('status.SUCCESS_STATUS'), self::MSG_SUCCESS,$count, $order);
            }
        } else {
            $status = $param->status;
            if ($status == 2) {
                $count = count(\app\common\model\Order::where(['createUser'=>$uid])->where('status',['=',2],['=',3],['=',8],'OR')->order('create_time desc')->select());
                $order = \app\common\model\Order::where(['createUser'=>$uid])->where('status',['=',2],['=',3],['=',8],'OR')->order('create_time desc')->limit($start,$length)->select();
            } else if ($status == 6) {
                $count = count(\app\common\model\Order::where(['createUser'=>$uid])->where('status', ['=',6],['=',10],['=',11],'OR')->order('update_time desc')->select());
                $order = \app\common\model\Order::where(['createUser'=>$uid])->where('status', ['=',6],['=',10],['=',11],'OR')->order('update_time desc')->limit($start,$length)->select();
            }else if($status == 4){
                $count = count(\app\common\model\Order::where(['createUser'=>$uid])->where('status', ['=',4],['=',7],'OR')->order('create_time desc')->select());
                $order = \app\common\model\Order::where(['createUser'=>$uid])->where('status', ['=',4],['=',7],'OR')->order('create_time desc')->limit($start,$length)->select();
            }
            else {
                $count = count(\app\common\model\Order::where(['createUser' => $uid, 'status' => $status])->order('create_time desc')->select());
                $order = \app\common\model\Order::where(['createUser' => $uid, 'status' => $status])->order('create_time desc')->limit($start,$length)->select();
            }

            if (empty($order)) {
                return show(config('status.EMPTY_STATUS'), self::NOT_DATA, '未查到订单信息');
            } else {
                for ($i = 0; $i < count($order); $i++) {
                    $orderProductDetail = Orderproductdetail::where('orderId', $order[$i]->id)->select();
                    $order[$i]['products'] = $orderProductDetail;
                }
                return show_page(config('status.SUCCESS_STATUS'), self::MSG_SUCCESS, $count,$order);
            }
        }
    }

    /**
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 订单详情
     */
    public function getOrderDetails()
    {
        $param = self::getHttpParam();
        if (empty($param->orderId)) {
            return show(config('status.ERROR_STATUS'), self::NOT_PARAM, 'orderId不能这空');
        } else {
            $orderId = $param->orderId;
            $order = \app\common\model\Order::where('id', $orderId)->find();
            //$store = \app\common\model\Store::get($order->storeId);
            $store = \app\common\model\Store::where('id', $order->storeId)->field('id,name,address,province,city,district')->find();
            //$order['storeName'] = $store->name;
            $order['storeInfo'] = $store;
            if (empty($order)) {
                return show(config('status.EMPTY_STATUS'), self::NOT_DATA, '未查到订单信息');
            } else {
                $orderProductDetail = Orderproductdetail::where('orderId', $order->id)->select();
                foreach ($orderProductDetail as &$v){
                    $Refundorder = Refundorder::where(['orderProductDetailId'=>$v['id']])->find();
                    if($Refundorder){
                        $v['Refund_time'] = $Refundorder->create_time;
                        $v['Refund_No'] = $Refundorder->out_refund_no;
                        $v['Refund_reason'] = $Refundorder->reason;
                        $v['Refund_fee'] = $Refundorder->refund_fee;
                        $v['actualrefund_fee'] = $Refundorder->actualrefund_fee;
                        $v['content'] = $Refundorder->content;
                        $v['Refundstatus'] = $Refundorder->status;
                        $Proofrefund = Proofrefund::where('refundId',$Refundorder->id)->find();
                        if($Proofrefund){
                            $v['voucherImg'] = explode(',',$Proofrefund->imgUrl);
                        }
                    }
                }

                $order['products'] = $orderProductDetail;

                return show(config('status.SUCCESS_STATUS'), self::MSG_SUCCESS, $order);
            }
        }
    }

    /**
     * @return \think\response\Json
     * 订单状态跟踪
     */
    public function getDadaOrderQuery(){
        $order_id = input("order_id");
        $orderModel = new \app\common\model\Order();
        $order = $orderModel->findOrder();
        $addOrder = new DadaAddOrder();
        $result = $addOrder->orderQuery($order_id);
        return show(config('status.SUCCESS_STATUS'), self::MSG_SUCCESS, $result);
    }

    private function queryStatusName($result)
    {

        switch ($result['statusCode']) {
            case 1:
                return "等待起手接单";
            case 2:
                return "待取货";
            case 3:
                return "配送中";
            case 4:
                return "已完成";
            case 5:
                return "已取消";
            case 7:
                return "已过期";
            case 8:
                return "指派单";
            case 9:
                return "妥投异常之物品返回中";
            case 10:
                return "妥投异常之物品返回完成";
            case 1000:
                return "创建达达运单失败";
        }
    }

    /**
     * @param $orderNO
     * 根据orderNO查询对应物流跟踪
     */
    private function dadaOrderQuery($orderNO){
        $distributionRecordModel = new Distributionrecord();
        return $distributionRecordModel->findDistributionRecords($orderNO);
    }

    /**
     * @param $order
     * @return mixed
     * 根据配送方式查询对应物流跟踪
     */
    private function deliverMethodOrderQuery($order){
        $orderModel = new \app\common\model\Order();
        //达达物流跟踪
        if($order->deliverMethod == $orderModel::DELIVERMETHOD_2){
            $orderNO = $order->orderNO;
            $dadaOrderQuery = $this->dadaOrderQuery($orderNO);
            $data = array();
            if($dadaOrderQuery && !empty($dadaOrderQuery)){
                $data['status'] = $orderModel::STATUS_VALID;
                $data['message'] = "获取物流跟踪成功";
                $data['result'] = $dadaOrderQuery;
            }else{
                $data['status'] = $orderModel::STATUS_INVALID;
                $data['message'] = "获取物流跟踪失败，数据空";
            }
        }
        return $data;
    }

    /**
     * @return \think\response\Json
     * 哒哒配送物流跟踪
     */
    public function orderQuery(){
       // $uid = TokenService::getCurrentUid();
        $orderNO = input('orderNO');

        $orderModel = new \app\common\model\Order();
        $data = array();
      //根据orderNO获取订单信息
     // $order = $orderModel->getOrderNoCurrentOrder($orderNO,$uid);
        $order = $orderModel->getOrderNoCurrentOrder($orderNO);

        if($order && !empty($order)) {
            //根据配送方式获取对应的物流跟踪
           $data = $this->deliverMethodOrderQuery($order);
            echo json_encode($data);exit;
        }

        return show($orderModel::STATUS_VALID,"获取物流跟踪成功",$data);
    }




    /**
     *获取达达预配送订单
     */
    public function queryDeliverFee(){
        $uid = TokenService::getCurrentUid();
        $param = Request::instance()->param();
        $id = $param['orderId'];
        $dadaAddOrder= new DadaAddOrder();
        if(!$id) {
            return show(config('status.ERROR_STATUS'), '参数id不能为空', array("id" => $id));
        }
//        $orderModel = new \app\common\model\Order();
        $tools = new ToolsInco();
        //$config = $tools->getDataConfig();
//        $order = $orderModel->getCurrentOrder($id);
//        if($order && !empty($order)){
//            $userAddress  = $order->deliverAddress;
//        }else{
//            return show(config('status.ERROR_STATUS'),'无效订单！',array("order"=>$order));
//        }
        $is_prepay = $tools::is_prepay_0;//是否需要垫付 1:是 0:否 (垫付订单金额，非运费)
        $data['shop_no'] = $param['storeId'];  //达达门店编号
        $data['is_prepay'] = $is_prepay;
        //根据地址获取收货人经纬度
        $gdparam['address'] = $param['address'];
        $TencentLatLng = BaseHelper::GeocoderAddress($gdparam['address']); //腾讯地图和高德地图使用的是同一坐标系
        //dump($TencentLatLng);exit;
        //$gaodeResult = $dadaAddOrder->getAddres($gdparam);
        //$res = json_decode($gaodeResult);
        //$location = explode(',',$res->geocodes[0]->location);
        $cityName =  $TencentLatLng['address_components']['city'];
        if(isset($cityName) && !empty($cityName)){
            //获取城市编码
            $city_code = $dadaAddOrder->getCityCode(['cityName'=>$cityName]);
        }else{
            return show(config('status.ERROR_STATUS'),'用户所在城市不能为空！',array("cityName"=>""));
        }
        $receiver_name = $param['userName'];                       //收货人
        $mobile = $param['userPhone'];                             //收货人手机号码
        if($receiver_name == "" || !$receiver_name){
            return show(config('status.ERROR_STATUS'),'收货人不能为空！',$receiver_name);
        }
        if($mobile == "" || !$mobile){
            return show(config('status.ERROR_STATUS'),'收货人电话不能为空！',"");
        }
        $cargo_price = $param['total'];
        $origin_id = $id;
        $receiver_lat =$TencentLatLng['location']['lat'];    //收货人地址经度
        $receiver_lng =$TencentLatLng['location']['lng'];    //收货人地址纬度
        $receiver_address = $param['address'];
        $callback = config('miniprogram.domain').'/api/DadaNotify/index';
        $data['origin_id'] =$origin_id;
        $data['city_code'] = $city_code->cityCode;
        $data['cargo_price'] = $cargo_price;
        $data['receiver_name'] = $receiver_name;
        $data['receiver_address'] = $receiver_address;
        $data['callback'] = $callback;
        $data['receiver_phone'] = $mobile;     //收货人手机号
        $data['receiver_lat'] = $receiver_lat;     //地址纬度
        $data['receiver_lng'] = $receiver_lng;     //地址经度
        $data['tips'] = 0;     //小费
        $dadaAddOrder = new DadaAddOrder();
        $result = $dadaAddOrder->queryDeliverFee($data);
        $result = $result['result'];
        $querydeliverfeeModel = new Querydeliverfee();
//        $result['createDate'] = date('Y-m-d h:i:s',time());
//       // $result['createOper'] = $tenantId;
//        $result['order_id'] = $id;
//        $result['createOper'] = $uid;
//        $result['id'] = get_uniqid_id();
//        $result['distance'] = round($result['distance']);
//        $result['createOper'] = input('createOper');
//        $res = $querydeliverfeeModel->insterQueryDeliverFee($result);
        $paramData['distance'] = $result['distance'];
        $paramData['fee'] = $result['fee'] ;
        $paramData['deliverFee'] = $result['deliverFee'];
        $paramData['couponFee'] = $result['couponFee'] ?? 0;
        return show(config('status.SUCCESS_STATUS'),'获取订单运费成功！',$paramData);
    }


    /**
     * @param $deliverMethod
     * @param $orderModel
     * @return false|\PDOStatement|string|\think\Collection
     * 根据配送方式获取对应的物流取消原因列表
     */
    private function getFormalCancel($deliverMethod,$orderModel){
        if($deliverMethod == $orderModel::DELIVERMETHOD_2){
            //获取达达配送取消订单原因列表
            $dadaReasonsModel = new Dadareasons();
            $result = $dadaReasonsModel->getFormalCancelList();
            return $result;
        }
    }


    /**
     * @param $cancel_reason_id
     */
    public function is_reason($cancel_reason_id,$dadaReasons,$cancel_reason){
        if($cancel_reason_id == $dadaReasons::REASON_10000){
            //判断取消订单其他原因是否为空
            if($cancel_reason == null){
                return array(
                    'status'=>config('status.ERROR_STATUS'),
                    'message'=>"取消订单其他原因不能为空！",
                    "data"=>array(
                        'cancel_reason'=>$cancel_reason
                    )
                );
            }else{
                return array(
                    'status'=>config('status.SUCCESS_STATUS'),
                    'message'=>"验证通过！",
                    "data"=>array(
                        'cancel_reason'=>$cancel_reason
                    )
                );
            }
        }
    }

    private function isCancelSuccess($formalCanel){
        $returnData['result'] = $formalCanel->getResult();
        $returnData['code'] = $formalCanel->getCode();
        $returnData['msg'] = $formalCanel->getMsg();
        $returnData['status'] = $formalCanel->getStatus();
        if($returnData['code'] == 0){
            $result = $returnData['result'];
            //取消订单违约金
            $deduct_fee	= $result['deduct_fee'];


        }else{
            return array(
                "code"=>$returnData['code'],
                "msg"=>$returnData['msg'],
                "status"=>$returnData['status'],
            );
        }
    }

    public function formalCancel(){
        $order_id = input("order_id");
        $cancel_reason_id = input("cancel_reason_id");
        $cancel_reason = input('cancel_reason');
        $dadaReasons = new Dadareasons();
        //如果取消原因为其他原因，判断cancel_reason不能为空
        $result = $this->is_reason($cancel_reason_id,$dadaReasons,$cancel_reason);
        if($result['status'] == config('status.ERROR_STATUS')){
            return show($result['status'],$result['message'],$result['data']);
        }
        $dada = new DadaAddOrder();
        $param['order_id']=$order_id;
        $param['cancel_reason_id'] = $cancel_reason_id;
        $param['cancel_reason'] = $cancel_reason;
        $formalCanel = $dada->formalCancel($param);
        //返回结果
        $result = $this->isCancelSuccess($formalCanel);


    }

    //获取订单取消原因
    public function getOrderFormalCancel(){
        $orderId = input('orderId');
        if($orderId && !empty($orderId)){
           $orderModel = new \app\common\model\Order();
           $order = $orderModel->getCurrentOrder($orderId);
           if($order && !empty($order)){
           //根据商户id获取商户设置的默认配送类型
           $deliverMethod = $order->deliverMethod;
           //配送订单取消原因查询
           $result = $this->getFormalCancel($deliverMethod,$orderModel);
           return show(config('status.SUCCESS_STATUS'),'获取达达配送取消订单原因成功',$result);
           }else{
               return show(config('status.ERROR_STATUS'),'获取订单失败！该订单不存在',['orderId'=>$orderId]);
           }
        }else{
            return show(config('status.ERROR_STATUS'),'orderId不能为空',['orderId'=>$orderId]);
        }
    }


    //订单物流查询
    public function getLogistics(){
        //\app\api\service\Token::getCurrentUid();
        (new getLogistics())->goCheck();
        $postData = input('post.');
        $ShipperCode = $postData['ShipperCode'];
        $LogisticCode = $postData['LogisticCode'];
        $kuaidiniao = new KuaiDiniaoApi();
        return $kuaidiniao->getOrderTracesByJson($ShipperCode,$LogisticCode);

    }

    //扫码核销
    public function WriteOffOrder(){
        //需要传递的参数storeid orderid
        (new WriteOffOrder())->goCheck();
        $postData = input('post.');
        //1.判断订单状态 2.判断订单与门店是否匹配
        //2.团购订单没有成功之前不能核销
        Db::startTrans();
        try{
            $this->checkWriteOffOrder($postData);
            //处理订单相关状态
            $orderModel = new \app\common\model\Order();
            $order = $orderModel->where('id',$postData['orderId'])->find();
            if($order->linkType == 1){
                $group = Groupdetail::where('orderId',$order->id)->find();
                if($group && $group->status == 1){
                    return show(config('status.ERROR_STATUS'),'该订单正在拼团中，不能核销或提货','不能核销或提货');
                }
            }
            if($order->type != 1){
                return show(config('status.ERROR_STATUS'),'该订单不是线下订单，不能核销','该订单不能核销');
            }
            $order->status = DictConstant::Order_Already_consumed;
            $order->writeoff_time = time();
            $order->save();
            $Orderproductdetail = new Orderproductdetail();
            $orderpro = $Orderproductdetail->where('orderId',$order->id)->select();
            $list = [];
            foreach ($orderpro as $value){
                array_push($list,['id'=>$value['id'],'oldStatus'=>DictConstant::Order_Already_consumed]);
            }
            $Orderproductdetail->saveAll($list);
            //修改消费明细状态
            $Useraccountdetails = Useraccountdetails::where('orderNO',$order->orderNO)->find();
            if($Useraccountdetails){
                $Useraccountdetails->payDate = date('Y-m-d H:i:s',$order->writeoff_time);
                $Useraccountdetails->save();
            }
            //判断该笔订单是否产生积分
            $Integral = new Integral();
            $Integral->XiaofeiSongjiFen($order);
            Db::commit();
            return show(config('status.SUCCESS_STATUS'),'核销或提货成功','核销或提货成功');
        }catch (Exception $ex){
            Db::rollback();
            return show(config('status.ERROR_STATUS'),$ex->msg,'核销或提货失败');
        }





    }

    private function checkWriteOffOrder($postData){
        $order = \app\common\model\Order::get($postData['orderId']);
        if(!$order){
            throw new ParameterException([
                'msg' => '该订单不存在'
            ]);
        }
        $store = Store::get($postData['storeId']);
        if(!$store){
            throw new ParameterException([
                'msg' => '该门店不存在'
            ]);
        }
        if($order->storeId != $postData['storeId']){
            throw new ParameterException([
                'msg' => '订单与门店不匹配'
            ]);
        }
        if($order->status != 8){
            throw new ParameterException([
                'msg' => '订单可能已经核销过了'
            ]);
        }
    }

    public function getOrderId(){
        $data = [];
        $data['orderId'] = BaseHelper::getUUID();
        return show(config('status.SUCCESS_STATUS'),'生成订单号成功',$data);
    }
}